package com.wuyan.web.auth.service;

import com.wuyan.web.auth.entity.PubAccountRole;
import com.wuyan.web.auth.entity.PubFunction;
import com.wuyan.web.auth.entity.PubRoleApi;
import com.wuyan.web.auth.entity.PubRoleFunction;
import com.wuyan.web.auth.form.PubAccountRoleForm;
import com.wuyan.web.auth.form.PubRoleApiForm;
import com.wuyan.web.auth.form.PubRoleFunctionForm;
import com.wuyan.web.auth.form.RoleAuthForm;
import com.wuyan.web.auth.repo.PubAccountRoleExtendRepo;
import com.wuyan.web.auth.repo.PubRoleApiRepoExtend;
import com.wuyan.web.auth.repo.PubRoleFunctionRepoExtend;
import com.wuyan.web.base.entity.PubAccount;
import com.wuyan.web.base.helper.auth.LoginInfo;
import com.wuyan.web.base.helper.convert.EncryptionUnReversibleConvert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IdentityService {

    @Autowired
    private PubRoleApiRepoExtend pubRoleApiRepoExtend;

    @Autowired
    private PubRoleFunctionRepoExtend pubRoleFunctionRepoExtend;

    @Autowired
    private PubRoleApiService pubRoleApiService;

    @Autowired
    private PubRoleFunctionService pubRoleFunctionService;

    @Autowired
    private PubAccountRoleExtendRepo pubAccountRoleExtendRepo;

    @Autowired
    private PubAccountRoleService pubAccountRoleService;

    @Autowired
    private PubAccountService pubAccountService;

    /**
     * 保存授权信息
     *
     * @param id   角色ID
     * @param form 授权数据
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean roleCreate(Integer id, RoleAuthForm form) throws Exception {
        // 先清空当前已授权记录
        pubRoleFunctionRepoExtend.deleteAllByRole(Collections.singletonList(id));
        pubRoleApiRepoExtend.deleteAllByRole(Collections.singletonList(id));

        if (null == form.getFunctions() || form.getFunctions().isEmpty()) {
            return true;
        }

        form.setFunctions(form.getFunctions().stream().peek(t -> t.setRoleId(id)).collect(Collectors.toList()));
        pubRoleFunctionService.creates(form.getFunctions());

        if (null == form.getApis() || form.getApis().isEmpty()) {
            return true;
        }

        form.setApis(form.getApis().stream().peek(t -> t.setRoleId(id)).collect(Collectors.toList()));
        pubRoleApiService.creates(form.getApis());

        return true;
    }

    /**
     * 获取指定角色的已授权功能概要
     *
     * @param id 角色ID
     */
    public RoleAuthForm roleGet(Integer id) {
        List<PubRoleApi> apis = pubRoleApiRepoExtend.findAllByRole(Collections.singletonList(id));
        List<PubRoleFunction> functions = pubRoleFunctionRepoExtend.findAllByRole(Collections.singletonList(id));

        return RoleAuthForm.builder()
                .apis(apis.stream().map(item -> {
                    PubRoleApiForm apiForm = PubRoleApiForm.builder().build();
                    BeanUtils.copyProperties(item, apiForm);
                    return apiForm;
                }).collect(Collectors.toList()))
                .functions(functions.stream().map(item -> {
                    PubRoleFunctionForm functionForm = PubRoleFunctionForm.builder().build();
                    BeanUtils.copyProperties(item, functionForm);
                    return functionForm;
                }).collect(Collectors.toList()))
                .build();
    }

    /**
     * 对用户账户的角色进行重新分配
     *
     * @param form 授权信息
     * @param id   账户ID
     * @return Object
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean accountCreate(Integer id, List<PubAccountRoleForm> form) throws Exception {
        // 先清空再分配
        List<PubAccountRole> pubAccountRoles = pubAccountRoleExtendRepo.findAllByUserId(id);
        if (null != pubAccountRoles && !pubAccountRoles.isEmpty()) {
            pubAccountRoleExtendRepo.deleteAll(pubAccountRoles);
        }

        if (null == form || form.isEmpty()) {
            return true;
        }

        form = form.stream()
                .peek(t -> {
                    t.setCfgTemp(0);
                    t.setUserId(id);
                    t.setStartTime(null);
                    t.setEndTime(null);
                })
                .collect(Collectors.toList());

        pubAccountRoleService.creates(form);

        return true;
    }

    /**
     * 临时授权：此操作会删除当前临时授权中相关的已授权角色记录
     *
     * @param form 临时授权信息
     * @param id   账户ID
     * @return Boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean accountTempCreate(Integer id, List<PubAccountRoleForm> form) throws Exception {
        if (null == form || form.isEmpty()) {
            return false;
        }

        // 剔除不符合规范的
        form = form.stream()
                .filter(t -> null != t.getStartTime() && null != t.getEndTime())
                .peek(t -> {
                    t.setCfgTemp(1);
                    t.setUserId(id);
                })
                .collect(Collectors.toList());

        // 先删除已存在的数据
        List<Integer> roleIds = form.stream().map(PubAccountRoleForm::getRoleId).collect(Collectors.toList());
        List<PubAccountRole> pubAccountRoles = pubAccountRoleExtendRepo.findAllByUserIdAndRoleIdIn(id, roleIds);
        if (null != pubAccountRoles && !pubAccountRoles.isEmpty()) {
            pubAccountRoleExtendRepo.deleteAll(pubAccountRoles);
        }

        pubAccountRoleService.creates(form);

        return true;
    }


    /**
     * 修改密码
     *
     * @param loginInfo 登录信息
     * @param pwd       密码
     * @return Boolean
     */
    public Boolean changePwd(LoginInfo loginInfo, String pwd) throws Exception {
        PubAccount account = loginInfo.getAccount();
        account.setPassword(EncryptionUnReversibleConvert.encode(pwd));
        loginInfo.setAccount(account);

        com.wuyan.web.auth.form.PubAccountForm pubAccount =
                com.wuyan.web.auth.form.PubAccountForm.builder().build();
        BeanUtils.copyProperties(account, pubAccount);

        pubAccountService.update(pubAccount, account.getId());

        return true;
    }

    /**
     * 获取当前登录账户下所有的已授权菜单
     *
     * @param loginInfo 登录信息
     * @return List<PubRole>
     */
    public List<PubFunction> getMenu(LoginInfo loginInfo) {
        List<com.wuyan.web.base.entity.PubFunction> menus = loginInfo.getMenus();
        if(null == menus) {
            return null;
        }

        return menus.stream().map(t -> {
            PubFunction build = PubFunction.builder().build();
            BeanUtils.copyProperties(t, build);
            return build;
        }).collect(Collectors.toList());
    }
}
